import { Injectable } from '@angular/core';
import {Actions, ofType, Effect} from '@ngrx/effects';
import {Observable, of , pipe} from 'rxjs';
import {Router} from '@angular/router';
import * as actions from '../actions/user.action';
import {
    LoadAction,
    AddAction,
    UpdateAction,
    DeleteAction,
    SearchAction
} from '../actions/user.action';
import { Action, Store , select} from '@ngrx/store';
import * as fromRoot from '../reducers';
import { switchMap, map, catchError , tap, withLatestFrom} from 'rxjs/operators';
import { User } from '../domain';
import { UserService } from '../services/user.service';
@Injectable()
export class UserEffects {
    @Effect()
    loadUsers$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.LOAD),
        map((a: LoadAction)  =>  a.payload),
        switchMap(projectId =>  this.userService.getUsersByProject(projectId).pipe(
            map(tasklists =>  new actions.LoadsuccessAction(tasklists)),
            catchError((err) =>  of(new actions.LoadFailAction(JSON.stringify(err))))
        ))
    );
    @Effect()
    addUserProjectRef$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.ADD),
        map((a: AddAction) =>  a.payload),
        switchMap(({user, projectId}) => this.userService.addProjectRef(user, projectId).pipe(
            map(u => new actions.AddSuccessAction(u)),
            catchError(err  =>  of(new actions.AddFailAction(err)))
        ))
    );
    @Effect()
    updateUserProjectRef$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.UPDATE),
        map((a: UpdateAction) => a.payload),
        switchMap(project => this.userService.batchUpdateProjectRef(project).pipe(
            map(users =>  new actions.UpdateSuccessAction(users)),
            catchError(err =>   of(new actions.UpdateFailAction(err)))
        ))
    );
    @Effect()
    delUserProjectRef$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.DELETE),
        map((a: DeleteAction) => a.payload),
        switchMap(({user, projectId}) => this.userService.removeProjectRef(user, projectId).pipe(
            map(u =>  new actions.DeletesuccessAction(u)),
            catchError(err =>   of(new actions.DeleteFailAction(err)))
        ))
    );
    @Effect()
    search$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.SEARCH),
        map((a: SearchAction) => a.payload),
        switchMap((str) => this.userService.searchUsers(str).pipe(
            map(users => new actions.SearchSuccessAction(users)),
            catchError(err =>   of(new actions.SearchFailAction(err)))
        )),
    );
    constructor(
        public actions$: Actions,
        public userService: UserService,
        public store$: Store<fromRoot.State>,
        public router: Router
      ) {}
}
